package presenter.code;

import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.*;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.*;
import presenter.code.entity.AccountEntity;
import presenter.code.entity.CodeEntity;
import utils.ThreadPool;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;

public class ExcelCreator {
    private final static String UTF8_ENCODING = "UTF-8";
    private final static String GBK_ENCODING = "GBK";

    private String path;
    private String name;
    private List<AccountEntity> accounts;
    private ExcelListener listener;

    public void create(String path, String name, List<AccountEntity> accounts, ExcelListener listener) {
        this.path = path;
        this.name = name;
        this.accounts = accounts;
        this.listener = listener;
        ThreadPool.work(() -> init(() -> write(listener::onSuccess)));
    }

    private WritableCellFormat cellWhite;
    private WritableCellFormat cellYellow;

    private void init(Runnable next) {
        WritableWorkbook book = null;
        try {
            listener.onStart();
            WritableFont fontContent = new WritableFont(WritableFont.ARIAL);
            fontContent.setPointSize(14);
            fontContent.setColour(Colour.BLACK);
            fontContent.setBoldStyle(WritableFont.NO_BOLD);
            fontContent.setItalic(false);
            fontContent.setUnderlineStyle(UnderlineStyle.NO_UNDERLINE);

            cellWhite = new WritableCellFormat(fontContent);
            cellWhite.setAlignment(Alignment.CENTRE);
            cellWhite.setVerticalAlignment(VerticalAlignment.CENTRE);
            cellWhite.setBackground(Colour.WHITE);
            cellWhite.setBorder(Border.ALL, BorderLineStyle.THIN);

            cellYellow = new WritableCellFormat(fontContent);
            cellYellow.setAlignment(Alignment.CENTRE);
            cellYellow.setVerticalAlignment(VerticalAlignment.CENTRE);
            cellYellow.setBackground(Colour.YELLOW);
            cellYellow.setBorder(Border.ALL, BorderLineStyle.THIN);

            File file = new File(fixedPath());
            file.deleteOnExit();
            file.createNewFile();
            book = Workbook.createWorkbook(file);
            book.createSheet("打码成绩", 0);
            book.write();
        } catch (Exception ex) {
            listener.onError(ex.getMessage());
        } finally {
            if (book != null) {
                try {
                    book.close();

                    next.run();
                } catch (Exception ex) {
                    listener.onError(ex.getMessage());
                }
            }
        }
    }

    private void write(Runnable next) {
        WritableWorkbook book = null;
        InputStream in = null;
        try {
            WorkbookSettings settings = new WorkbookSettings();
            settings.setEncoding(UTF8_ENCODING);
            in = new FileInputStream(fixedPath());
            Workbook workbook = Workbook.getWorkbook(in);
            book = Workbook.createWorkbook(new File(fixedPath()), workbook);
            WritableSheet sheet = book.getSheet(0);
            int row = 0;
            for (AccountEntity account : accounts) {
                int col = 0;
                sheet.addCell(new Label(col++, row, account.accountTip(), bgAccount(account)));//账号
                sheet.mergeCells(0, row, 0, row + 1);
                sheet.setColumnView(0, 20);
                List<CodeEntity> codes = account.codes();
                for (CodeEntity code : codes) {
                    sheet.addCell(new Label(col, row, code.code(), cellWhite));
                    sheet.addCell(new Label(col, row + 1, code.time(), bgTime(code)));
                    col++;
                }
                row += 2;
            }

            book.write();

        } catch (Exception ex) {
            listener.onError(ex.getMessage());
        } finally {
            if (book != null) {
                try {
                    book.close();

                    next.run();
                } catch (Exception ex) {
                    listener.onError(ex.getMessage());
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (Exception ex) {
                    listener.onError(ex.getMessage());
                }
            }
        }
    }

    private String fixedPath() {
        return path + name;
    }

    private WritableCellFormat bgAccount(AccountEntity account) {
        return account.overTime() ? cellYellow : cellWhite;
    }

    private WritableCellFormat bgTime(CodeEntity code) {
        return code.timeOver() ? cellYellow : cellWhite;
    }

    public interface ExcelListener {
        void onStart();

        void onSuccess();

        void onError(String msg);
    }
}
